package metadata

import (
	"encoding/json"
	"fmt"
	"sync"
	"time"
)

// MetadataType 表示元数据类型
type MetadataType string

const (
	// MetadataTypeTopic 表示主题元数据
	MetadataTypeTopic MetadataType = "topic"
	// MetadataTypePartition 表示分区元数据
	MetadataTypePartition MetadataType = "partition"
	// MetadataTypeReplica 表示副本元数据
	MetadataTypeReplica MetadataType = "replica"
	// MetadataTypeNode 表示节点元数据
	MetadataTypeNode MetadataType = "node"
	// MetadataTypeClient 表示客户端元数据
	MetadataTypeClient MetadataType = "client"
)

// Metadata 表示元数据
type Metadata struct {
	// Type 是元数据类型
	Type MetadataType
	// ID 是元数据ID
	ID string
	// Data 是元数据内容
	Data map[string]interface{}
	// Version 是元数据版本
	Version uint64
	// CreatedAt 是创建时间
	CreatedAt time.Time
	// UpdatedAt 是更新时间
	UpdatedAt time.Time
}

// NewMetadata 创建一个新的元数据
func NewMetadata(metadataType MetadataType, id string, data map[string]interface{}) *Metadata {
	now := time.Now()
	return &Metadata{
		Type:      metadataType,
		ID:        id,
		Data:      data,
		Version:   1,
		CreatedAt: now,
		UpdatedAt: now,
	}
}

// Update 更新元数据
func (m *Metadata) Update(data map[string]interface{}) {
	m.Data = data
	m.Version++
	m.UpdatedAt = time.Now()
}

// GetString 获取字符串值
func (m *Metadata) GetString(key string) (string, bool) {
	value, ok := m.Data[key]
	if !ok {
		return "", false
	}
	strValue, ok := value.(string)
	return strValue, ok
}

// GetInt 获取整数值
func (m *Metadata) GetInt(key string) (int, bool) {
	value, ok := m.Data[key]
	if !ok {
		return 0, false
	}
	switch v := value.(type) {
	case int:
		return v, true
	case float64:
		return int(v), true
	default:
		return 0, false
	}
}

// GetFloat 获取浮点值
func (m *Metadata) GetFloat(key string) (float64, bool) {
	value, ok := m.Data[key]
	if !ok {
		return 0, false
	}
	switch v := value.(type) {
	case float64:
		return v, true
	case int:
		return float64(v), true
	default:
		return 0, false
	}
}

// GetBool 获取布尔值
func (m *Metadata) GetBool(key string) (bool, bool) {
	value, ok := m.Data[key]
	if !ok {
		return false, false
	}
	boolValue, ok := value.(bool)
	return boolValue, ok
}

// GetMap 获取映射值
func (m *Metadata) GetMap(key string) (map[string]interface{}, bool) {
	value, ok := m.Data[key]
	if !ok {
		return nil, false
	}
	mapValue, ok := value.(map[string]interface{})
	return mapValue, ok
}

// GetArray 获取数组值
func (m *Metadata) GetArray(key string) ([]interface{}, bool) {
	value, ok := m.Data[key]
	if !ok {
		return nil, false
	}
	arrayValue, ok := value.([]interface{})
	return arrayValue, ok
}

// ToJSON 转换为JSON
func (m *Metadata) ToJSON() ([]byte, error) {
	return json.Marshal(m)
}

// FromJSON 从JSON转换
func FromJSON(data []byte) (*Metadata, error) {
	var metadata Metadata
	err := json.Unmarshal(data, &metadata)
	if err != nil {
		return nil, err
	}
	return &metadata, nil
}

// MetadataStore 表示元数据存储接口
type MetadataStore interface {
	// Get 获取元数据
	Get(metadataType MetadataType, id string) (*Metadata, bool)
	// Put 存储元数据
	Put(metadata *Metadata) error
	// Delete 删除元数据
	Delete(metadataType MetadataType, id string) error
	// List 列出元数据
	List(metadataType MetadataType) ([]*Metadata, error)
}

// InMemoryMetadataStore 表示内存元数据存储
type InMemoryMetadataStore struct {
	// data 是元数据映射表
	data map[MetadataType]map[string]*Metadata
	// mu 是互斥锁
	mu sync.RWMutex
}

// NewInMemoryMetadataStore 创建一个新的内存元数据存储
func NewInMemoryMetadataStore() *InMemoryMetadataStore {
	return &InMemoryMetadataStore{
		data: make(map[MetadataType]map[string]*Metadata),
	}
}

// Get 获取元数据
func (s *InMemoryMetadataStore) Get(metadataType MetadataType, id string) (*Metadata, bool) {
	s.mu.RLock()
	defer s.mu.RUnlock()

	typeMap, ok := s.data[metadataType]
	if !ok {
		return nil, false
	}

	metadata, ok := typeMap[id]
	return metadata, ok
}

// Put 存储元数据
func (s *InMemoryMetadataStore) Put(metadata *Metadata) error {
	s.mu.Lock()
	defer s.mu.Unlock()

	typeMap, ok := s.data[metadata.Type]
	if !ok {
		typeMap = make(map[string]*Metadata)
		s.data[metadata.Type] = typeMap
	}

	typeMap[metadata.ID] = metadata
	return nil
}

// Delete 删除元数据
func (s *InMemoryMetadataStore) Delete(metadataType MetadataType, id string) error {
	s.mu.Lock()
	defer s.mu.Unlock()

	typeMap, ok := s.data[metadataType]
	if !ok {
		return nil
	}

	delete(typeMap, id)
	return nil
}

// List 列出元数据
func (s *InMemoryMetadataStore) List(metadataType MetadataType) ([]*Metadata, error) {
	s.mu.RLock()
	defer s.mu.RUnlock()

	typeMap, ok := s.data[metadataType]
	if !ok {
		return []*Metadata{}, nil
	}

	result := make([]*Metadata, 0, len(typeMap))
	for _, metadata := range typeMap {
		result = append(result, metadata)
	}
	return result, nil
}

// MetadataManager 表示元数据管理器
type MetadataManager struct {
	// store 是元数据存储
	store MetadataStore
	// listeners 是监听器映射表
	listeners map[MetadataType][]MetadataListener
	// mu 是互斥锁
	mu sync.RWMutex
}

// MetadataListener 表示元数据监听器
type MetadataListener interface {
	// OnMetadataCreated 处理元数据创建事件
	OnMetadataCreated(metadata *Metadata)
	// OnMetadataUpdated 处理元数据更新事件
	OnMetadataUpdated(metadata *Metadata)
	// OnMetadataDeleted 处理元数据删除事件
	OnMetadataDeleted(metadataType MetadataType, id string)
}

// NewMetadataManager 创建一个新的元数据管理器
func NewMetadataManager(store MetadataStore) *MetadataManager {
	if store == nil {
		store = NewInMemoryMetadataStore()
	}
	return &MetadataManager{
		store:     store,
		listeners: make(map[MetadataType][]MetadataListener),
	}
}

// AddListener 添加监听器
func (mm *MetadataManager) AddListener(metadataType MetadataType, listener MetadataListener) {
	mm.mu.Lock()
	defer mm.mu.Unlock()

	listeners, ok := mm.listeners[metadataType]
	if !ok {
		listeners = make([]MetadataListener, 0)
	}
	mm.listeners[metadataType] = append(listeners, listener)
}

// RemoveListener 移除监听器
func (mm *MetadataManager) RemoveListener(metadataType MetadataType, listener MetadataListener) bool {
	mm.mu.Lock()
	defer mm.mu.Unlock()

	listeners, ok := mm.listeners[metadataType]
	if !ok {
		return false
	}

	for i, l := range listeners {
		if l == listener {
			mm.listeners[metadataType] = append(listeners[:i], listeners[i+1:]...)
			return true
		}
	}
	return false
}

// Get 获取元数据
func (mm *MetadataManager) Get(metadataType MetadataType, id string) (*Metadata, bool) {
	return mm.store.Get(metadataType, id)
}

// Create 创建元数据
func (mm *MetadataManager) Create(metadataType MetadataType, id string, data map[string]interface{}) (*Metadata, error) {
	// 检查是否已存在
	if _, exists := mm.Get(metadataType, id); exists {
		return nil, fmt.Errorf("metadata %s of type %s already exists", id, metadataType)
	}

	// 创建元数据
	metadata := NewMetadata(metadataType, id, data)

	// 存储元数据
	err := mm.store.Put(metadata)
	if err != nil {
		return nil, err
	}

	// 触发事件
	mm.notifyCreated(metadata)

	return metadata, nil
}

// Update 更新元数据
func (mm *MetadataManager) Update(metadataType MetadataType, id string, data map[string]interface{}) (*Metadata, error) {
	// 获取元数据
	metadata, exists := mm.Get(metadataType, id)
	if !exists {
		return nil, fmt.Errorf("metadata %s of type %s not found", id, metadataType)
	}

	// 更新元数据
	metadata.Update(data)

	// 存储元数据
	err := mm.store.Put(metadata)
	if err != nil {
		return nil, err
	}

	// 触发事件
	mm.notifyUpdated(metadata)

	return metadata, nil
}

// Delete 删除元数据
func (mm *MetadataManager) Delete(metadataType MetadataType, id string) error {
	// 检查是否存在
	if _, exists := mm.Get(metadataType, id); !exists {
		return nil
	}

	// 删除元数据
	err := mm.store.Delete(metadataType, id)
	if err != nil {
		return err
	}

	// 触发事件
	mm.notifyDeleted(metadataType, id)

	return nil
}

// List 列出元数据
func (mm *MetadataManager) List(metadataType MetadataType) ([]*Metadata, error) {
	return mm.store.List(metadataType)
}

// notifyCreated 通知元数据创建
func (mm *MetadataManager) notifyCreated(metadata *Metadata) {
	mm.mu.RLock()
	defer mm.mu.RUnlock()

	listeners, ok := mm.listeners[metadata.Type]
	if !ok {
		return
	}

	for _, listener := range listeners {
		listener.OnMetadataCreated(metadata)
	}
}

// notifyUpdated 通知元数据更新
func (mm *MetadataManager) notifyUpdated(metadata *Metadata) {
	mm.mu.RLock()
	defer mm.mu.RUnlock()

	listeners, ok := mm.listeners[metadata.Type]
	if !ok {
		return
	}

	for _, listener := range listeners {
		listener.OnMetadataUpdated(metadata)
	}
}

// notifyDeleted 通知元数据删除
func (mm *MetadataManager) notifyDeleted(metadataType MetadataType, id string) {
	mm.mu.RLock()
	defer mm.mu.RUnlock()

	listeners, ok := mm.listeners[metadataType]
	if !ok {
		return
	}

	for _, listener := range listeners {
		listener.OnMetadataDeleted(metadataType, id)
	}
}
